{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lLGpv1fLLIjF"
   },
   "source": [
    "# Adalflow RAG Playbook example\n",
    "\n",
    "There are different patterns to build a RAG:\n",
    "\n",
    "- RAG with separate data process pipeline and a RAG task pipeline. This fits into a scenario where there is lots of data in production database, and we preprocess the data to embeddings and then we build a RAG task pipeline that retrieves context in multiple stages.\n",
    "\n",
    "- RAG with dynamic data access and caching the embedding dynamically in a local storage.\n",
    "\n",
    "Here we will have have a look at an example with a local DB using FAISS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "sfKEfaYC3Go7"
   },
   "outputs": [],
   "source": [
    "from IPython.display import clear_output\n",
    "\n",
    "!pip install -U adalflow[openai,groq,faiss-cpu]\n",
    "\n",
    "clear_output()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip uninstall httpx anyio -y\n",
    "!pip install \"anyio>=3.1.0,<4.0\"\n",
    "!pip install httpx==0.24.1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "-4c_AGBt3PlR",
    "outputId": "275b050a-ce64-4b40-a5f9-4ccc12d92add"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Please enter your OpenAI API key: ··········\n",
      "Please enter your GROQ API key: ··········\n",
      "API keys have been set.\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from getpass import getpass\n",
    "\n",
    "# Prompt user to enter their API keys securely\n",
    "openai_api_key = getpass(\"Please enter your OpenAI API key: \")\n",
    "groq_api_key = getpass(\"Please enter your GROQ API key: \")\n",
    "\n",
    "# Set environment variables\n",
    "os.environ[\"OPENAI_API_KEY\"] = openai_api_key\n",
    "os.environ[\"GROQ_API_KEY\"] = groq_api_key\n",
    "\n",
    "print(\"API keys have been set.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4NztjiLR_EQE"
   },
   "source": [
    "## Design\n",
    "\n",
    "Some libraries may use hooks [2] and callbacks [3] [4], or advanced web-based debugging tools [5] [6] [7]. Hooks and callbacks are conceptually similar in that they both allow users to execute custom code at specific points during the execution of a program. Both provide mechanisms to inject additional behavior in response to certain events or conditions, without modifying the core logic. PyTorch defines, registers, and executes hooks mainly in its base classes like nn.Module and Tensor, without polluting the functional and user-facing APIs.\n",
    "\n",
    "At this point, our objectives are:\n",
    "\n",
    "1. Maximize debugging capabilities via the simple logging module to keep the source code clean.\n",
    "\n",
    "2. Additionally, as we can’t always control the outputs of generators, we will provide customized logger and tracers(drop-in decorators) for them, for which we will explain in Tracing. This will not break the first objective.\n",
    "\n",
    "In the future, when we have more complex requirements from users, we will consider adding hooks/callbacks but we will do it in a way to keep the functional and user-facing APIs clean."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "id": "d2H1vYoC_F-g"
   },
   "outputs": [],
   "source": [
    "import logging\n",
    "\n",
    "log = logging.getLogger(__name__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "id": "e2GxAapG_TJH"
   },
   "outputs": [],
   "source": [
    "from adalflow.utils.logger import get_logger\n",
    "\n",
    "\n",
    "root_logger = get_logger()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "Yk4oiBFE_asG",
    "outputId": "470e30dc-1b31-40c1-9e48-30754ae54b45"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[32m2024-11-28 13:39:41 - [<ipython-input-5-9bd1accb40e0>:3:<cell line: 3>] - All logging examples are done. Feeling green!\u001b[0m\n"
     ]
    }
   ],
   "source": [
    "from adalflow.utils.logger import printc\n",
    "\n",
    "printc(\"All logging examples are done. Feeling green!\", color=\"green\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "B8lmlT_9_nVP"
   },
   "source": [
    "Set up all logs in one file\n",
    "\n",
    "Assume your source code is at src/task.py. You can log simply by:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "o_Ru1myM_c-J"
   },
   "outputs": [],
   "source": [
    "import logging\n",
    "\n",
    "log = logging.getLogger(__name__)\n",
    "\n",
    "\n",
    "class Task:\n",
    "    def __init__(self):\n",
    "        log.info(\"This is a user program child logger\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "o7YPjEZk_ehg",
    "outputId": "ad0f58e9-6f5c-4d00-e737-2fa1ad5ebd85"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2024-11-28 13:39:46 - <ipython-input-7-f4c1161cc964> - INFO - [<ipython-input-7-f4c1161cc964>:9:<cell line: 9>] - This is the log in the main file\n"
     ]
    }
   ],
   "source": [
    "import logging\n",
    "from adalflow.utils.logger import get_logger\n",
    "\n",
    "root_logger = get_logger(level=\"DEBUG\", save_dir=\"./logs\")  # log to ./logs/lib.log\n",
    "\n",
    "# run code from the library components such as generator\n",
    "# ....\n",
    "\n",
    "root_logger.info(\"This is the log in the main file\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Db1_Ob3X_gpe"
   },
   "source": [
    "Separate library and application logs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "rQWuFnUc_gNm"
   },
   "outputs": [],
   "source": [
    "from adalflow.utils.logger import get_logger\n",
    "\n",
    "app_logger = get_logger(\n",
    "    name=\"my_app\", level=\"DEBUG\", save_dir=\"./logs\"\n",
    ")  # log to ./logs/my_app.log\n",
    "\n",
    "\n",
    "class Task:\n",
    "    def __init__(self):\n",
    "        app_logger.info(\"This is a user program child logger\")"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  },
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
